﻿// Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml.Linq;

using MyTravelPostWebsite.MyTravelPostService;
using System.Collections.Generic;

namespace MyTravelPostWebsite
{
    public partial class TravelPage : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // check the post back
            if (IsPostBack)
            {
                return;
            }

            // get the blog id from the page request.
            int blogID = 0;
            int.TryParse(Request.Params["BlogID"], out blogID);

            // create a short lived service and request for latest blog post
            using (MyTravelPostServiceClient travelEntitiesService = new MyTravelPostServiceClient())
            {
                Blog blog = travelEntitiesService.GetBlog(blogID);
                BlogPost post = travelEntitiesService.GetLatestBlogPosting(blog);

                if (null != post)
                {
                    // fill in the new text.
                    labelBlogTitle.Text = post.BlogTitle;
                    labelSeries.Text = blog.SeriesTitle;
                    labelPerson.Text = blog.BlogWriter.Name;
                    blogEntry.Text = post.BlogEntry;

                    // call the methods to update the comments.
                    UpdateCommentsList(post);

                    var people = travelEntitiesService.GetPeople();

                    // not set all the people in the dropdown list
                    dropdownPersons.DataTextField = "Name";
                    dropdownPersons.DataSource = people;
                    dropdownPersons.DataBind();

                    dropdownBlogPersonChange.DataTextField = "Name";
                    dropdownBlogPersonChange.DataSource = people;
                    dropdownBlogPersonChange.DataBind();                    

                    // setup the viewstate that we need in the submit button
                    ViewState["BlogPost"] = post;
                    ViewState["People"] = people;
                    ViewState["Blog"] = blog;
                }
            }
        }

        // on submit, we need to add a comment that's associated to the blog post.
        protected void buttonSubmitComment_Click(object sender, EventArgs e)
        {
            // create a short lived service and send back the travel blogs.
            using (MyTravelPostServiceClient travelEntitiesService = new MyTravelPostServiceClient())
            {
                BlogPost post = (BlogPost)ViewState["BlogPost"];
                List<Person> peopleList = (List<Person>)ViewState["People"];

                // get the person from the people list
                Person person = peopleList[dropdownPersons.SelectedIndex];

                Comment newComment = new Comment();
                newComment.CommentText = textComment.Text;
                
                // what we are doing here is setting up the relationships, similar
                // to a foriegn key. If you didn't have the EntityKey on the reference
                // then you would have to send all the related ends.
                // this case we can optimize and build the relationships
                // and send them down to be added in the ObjectContext.
                newComment.PersonReference = new EntityReferenceOfPersonXC1u02lO();
                newComment.PersonReference.EntityKey = person.EntityKey;
                newComment.BlogPostReference = new EntityReferenceOfBlogPostXC1u02lO();
                newComment.BlogPostReference.EntityKey = post.EntityKey;

                // call the service that adds the comment to the database.
                newComment = travelEntitiesService.AddComment(newComment);

                newComment.CommentWriter = person;

                // add to the overall list of comments, and update the post.
                post.PostComments.Add(newComment);

                // clear the text.
                textComment.Text = "";
                    
                // call the methods to update the comments on the field
                UpdateCommentsList(post);

                // reload page so that F5, refresh doesn't update all this data.
                ReloadPage();
            }
        }

        private void ReloadPage()
        {
            // get the blog and reload this page so that refresh won't give us
            // bad data.
            Blog blog = (Blog)ViewState["Blog"];

            // launch this page again.
            Response.Redirect("TravelPage.aspx?BlogID=" + blog.BlogID);
        }

        private void UpdateCommentsList(BlogPost post)
        {
            // get all the comments with people and load the comments grid.
            var comments = from c in post.PostComments
                           select new
                           {
                               Author = c.CommentWriter.Name,
                               WhatISaid = c.CommentText,
                           };

            // reset the blog post into comments.
            ViewState["BlogPost"] = post;
            gridComments.DataSource = comments;
            gridComments.DataBind();
        }

        protected void gridComments_RowDeleted(object sender, GridViewDeletedEventArgs e)
        {
            // we did all the work in RowDeleting
        }

        protected void gridComments_RowDeleting(object sender, GridViewDeleteEventArgs e)
        {
            // create a short lived service and send back the travel blogs.
            using (MyTravelPostServiceClient travelEntitiesService = new MyTravelPostServiceClient())
            {
                // get the comment that is being marked for deletion
                // and get the view state blog post.
                BlogPost post = (BlogPost)ViewState["BlogPost"];
                
                // move the comment to the deleted comment selection.                
                Comment deletedComment = post.PostComments[e.RowIndex];
                
                // remove the post comment from the deleted item.
                post.PostComments.RemoveAt(e.RowIndex);

                // serialize the post and the deleted comments back to view state.
                ViewState["BlogPost"] = post;

                // call the DeleteComment service
                travelEntitiesService.DeleteComment(deletedComment);
                
                // update the comments
                UpdateCommentsList(post);
                
                // reload page so that F5, refresh doesn't update all this data.
                ReloadPage();            
            }
        }

        protected void buttonUpdate_Click(object sender, EventArgs e)
        {
            // create the update service
            using (MyTravelPostServiceClient travelEntitiesService = new MyTravelPostServiceClient())
            {
                // here we are going to take every other comment and put (*) at the end.
                // this is just to show how to make the web service call and update
                // items on the other end.
                BlogPost post = (BlogPost)ViewState["BlogPost"];
                List<Comment> updatedComments = new List<Comment>();

                // this bool value is so we can pass in a subset of items to updated.
                bool toupdate = true;
                foreach (Comment c in post.PostComments)
                {
                    if (toupdate)
                    {
                        // create a new comment and just set the id and entity key
                        // that's all we need to update the new comment text.
                        Comment newComment = new Comment();
                        newComment.EntityKey = c.EntityKey;
                        newComment.CommentID = c.CommentID;
                        newComment.CommentText = c.CommentText + "*";
                        
                        updatedComments.Add(newComment);
                        toupdate = false;
                    }
                    else
                    {
                        toupdate = true;
                    }
                }

                // even through the comments are also attached to the post
                // we can drop and just send the updated items. This helps in 
                // reducing the amount of data going through the service.
                post.PostComments 
                    = travelEntitiesService.UpdateComments(post.PostComments, updatedComments);

                // update the view state, and be sure to update the gridview
                ViewState["BlogPost"] = post;
                UpdateCommentsList(post);

                // reload page so that F5, refresh doesn't update all this data.
                ReloadPage();
            }
        }

        protected void ChangeOwner_Click(object sender, EventArgs e)
        {
            // create the update service
            using (MyTravelPostServiceClient travelEntitiesService = new MyTravelPostServiceClient())
            {
                // here we are going to take every other comment and put (*) at the end.
                // this is just to show how to make the web service call and update
                // items on the other end.
                Blog blog = (Blog)ViewState["Blog"];
                
                // get the person from the people list
                List<Person> peopleList = (List<Person>)ViewState["People"];
                Person person = peopleList[dropdownBlogPersonChange.SelectedIndex];
                EntityKey personKey = person.EntityKey;

                // use the key from the person to change the ownship of this blog
                travelEntitiesService.ChangeBlogowner(blog, personKey);

                // reload page so that F5, refresh doesn't update all this data.
                ReloadPage();
            }
        }
    }
}
